home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1998 February / CD WARE MULTIMEDIA (02-1998) CD++.iso / Encript / SNOW / SOURCE.ZIP / snow / ice.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-28  |  7.2 KB  |  395 lines

  1. /*
  2.  * Implementation of the ICE encryption algorithm.
  3.  *
  4.  * Written by Matthew Kwan - July 1996
  5.  */
  6.  
  7. #include "ice.h"
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11.  
  12.     /* Structure of a single round subkey */
  13. typedef unsigned long    ICE_SUBKEY[3];
  14.  
  15.  
  16.     /* Internal structure of the ICE_KEY structure */
  17. struct ice_key_struct {
  18.     int        ik_size;
  19.     int        ik_rounds;
  20.     ICE_SUBKEY    *ik_keysched;
  21. };
  22.  
  23.     /* The S-boxes */
  24. static unsigned long    ice_sbox[4][1024];
  25. static int        ice_sboxes_initialised = 0;
  26.  
  27.  
  28.     /* Modulo values for the S-boxes */
  29. static const int    ice_smod[4][4] = {
  30.                 {333, 313, 505, 369},
  31.                 {379, 375, 319, 391},
  32.                 {361, 445, 451, 397},
  33.                 {397, 425, 395, 505}};
  34.  
  35.     /* XOR values for the S-boxes */
  36. static const int    ice_sxor[4][4] = {
  37.                 {0x83, 0x85, 0x9b, 0xcd},
  38.                 {0xcc, 0xa7, 0xad, 0x41},
  39.                 {0x4b, 0x2e, 0xd4, 0x33},
  40.                 {0xea, 0xcb, 0x2e, 0x04}};
  41.  
  42.     /* Expanded permutation values for the P-box */
  43. static const unsigned long    ice_pbox[32] = {
  44.         0x00000001, 0x00000080, 0x00000400, 0x00002000,
  45.         0x00080000, 0x00200000, 0x01000000, 0x40000000,
  46.         0x00000008, 0x00000020, 0x00000100, 0x00004000,
  47.         0x00010000, 0x00800000, 0x04000000, 0x20000000,
  48.         0x00000004, 0x00000010, 0x00000200, 0x00008000,
  49.         0x00020000, 0x00400000, 0x08000000, 0x10000000,
  50.         0x00000002, 0x00000040, 0x00000800, 0x00001000,
  51.         0x00040000, 0x00100000, 0x02000000, 0x80000000};
  52.  
  53.     /* The key rotation schedule */
  54. static const int    ice_keyrot[16] = {
  55.                 0, 1, 2, 3, 2, 1, 3, 0,
  56.                 1, 3, 2, 0, 3, 1, 0, 2};
  57.  
  58.  
  59. /*
  60.  * Galois Field multiplication of a by b, modulo m.
  61.  * Just like arithmetic multiplication, except that additions and
  62.  * subtractions are replaced by XOR.
  63.  */
  64.  
  65. static int
  66. gf_mult (
  67.     register int    a,
  68.     register int    b,
  69.     register int    m
  70. ) {
  71.     register int    res = 0;
  72.  
  73.     while (b) {
  74.         if (b & 1)
  75.         res ^= a;
  76.  
  77.         a <<= 1;
  78.         b >>= 1;
  79.  
  80.         if (a >= 256)
  81.         a ^= m;
  82.     }
  83.  
  84.     return (res);
  85. }
  86.  
  87.  
  88. /*
  89.  * Galois Field exponentiation.
  90.  * Raise the base to the power of 7, modulo m.
  91.  */
  92.  
  93. static int
  94. gf_exp7 (
  95.     register int    b,
  96.     int        m
  97. ) {
  98.     register int    x;
  99.  
  100.     if (b == 0)
  101.         return (0);
  102.  
  103.     x = gf_mult (b, b, m);
  104.     x = gf_mult (b, x, m);
  105.     x = gf_mult (x, x, m);
  106.     return (gf_mult (b, x, m));
  107. }
  108.  
  109.  
  110. /*
  111.  * Carry out the ICE 32-bit P-box permutation.
  112.  */
  113.  
  114. static unsigned long
  115. ice_perm32 (
  116.     register unsigned long    x
  117. ) {
  118.     register unsigned long        res = 0;
  119.     register const unsigned long    *pbox = ice_pbox;
  120.  
  121.     while (x) {
  122.         if (x & 1)
  123.         res |= *pbox;
  124.         pbox++;
  125.         x >>= 1;
  126.     }
  127.  
  128.     return (res);
  129. }
  130.  
  131.  
  132. /*
  133.  * Initialise the ICE S-boxes.
  134.  * This only has to be done once.
  135.  */
  136.  
  137. static void
  138. ice_sboxes_init (void)
  139. {
  140.     register int    i;
  141.  
  142.     for (i=0; i<1024; i++) {
  143.         int            col = (i >> 1) & 0xff;
  144.         int            row = (i & 0x1) | ((i & 0x200) >> 8);
  145.         unsigned long    x;
  146.  
  147.         x = gf_exp7 (col ^ ice_sxor[0][row], ice_smod[0][row]) << 24;
  148.         ice_sbox[0][i] = ice_perm32 (x);
  149.  
  150.         x = gf_exp7 (col ^ ice_sxor[1][row], ice_smod[1][row]) << 16;
  151.         ice_sbox[1][i] = ice_perm32 (x);
  152.  
  153.         x = gf_exp7 (col ^ ice_sxor[2][row], ice_smod[2][row]) << 8;
  154.         ice_sbox[2][i] = ice_perm32 (x);
  155.  
  156.         x = gf_exp7 (col ^ ice_sxor[3][row], ice_smod[3][row]);
  157.         ice_sbox[3][i] = ice_perm32 (x);
  158.     }
  159. }
  160.  
  161.  
  162. /*
  163.  * Create a new ICE key.
  164.  */
  165.  
  166. ICE_KEY *
  167. ice_key_create (
  168.     int        n
  169. ) {
  170.     ICE_KEY        *ik;
  171.  
  172.     if (!ice_sboxes_initialised) {
  173.         ice_sboxes_init ();
  174.         ice_sboxes_initialised = 1;
  175.     }
  176.  
  177.     if ((ik = (ICE_KEY *) malloc (sizeof (ICE_KEY))) == NULL)
  178.         return (NULL);
  179.  
  180.     if (n < 1) {
  181.         ik->ik_size = 1;
  182.         ik->ik_rounds = 8;
  183.     } else {
  184.         ik->ik_size = n;
  185.         ik->ik_rounds = n * 16;
  186.     }
  187.  
  188.     if ((ik->ik_keysched = (ICE_SUBKEY *) malloc (ik->ik_rounds
  189.                     * sizeof (ICE_SUBKEY))) == NULL) {
  190.         free (ik);
  191.         return (NULL);
  192.     }
  193.  
  194.     return (ik);
  195. }
  196.  
  197.  
  198. /*
  199.  * Destroy an ICE key.
  200.  * Zero out the memory to prevent snooping.
  201.  */
  202.  
  203. void
  204. ice_key_destroy (
  205.     ICE_KEY        *ik
  206. ) {
  207.     int        i, j;
  208.  
  209.     if (ik == NULL)
  210.         return;
  211.  
  212.     for (i=0; i<ik->ik_rounds; i++)
  213.         for (j=0; j<3; j++)
  214.         ik->ik_keysched[i][j] = 0;
  215.  
  216.     ik->ik_rounds = ik->ik_size = 0;
  217.  
  218.     if (ik->ik_keysched != NULL)
  219.         free (ik->ik_keysched);
  220.  
  221.     free (ik);
  222. }
  223.  
  224.  
  225. /*
  226.  * The single round ICE f function.
  227.  */
  228.  
  229. static unsigned long
  230. ice_f (
  231.     register unsigned long    p,
  232.     const ICE_SUBKEY    sk
  233. ) {
  234.     unsigned long    tl, tr;        /* Expanded 40-bit values */
  235.     unsigned long    al, ar;        /* Salted expanded 40-bit values */
  236.  
  237.                     /* Left half expansion */
  238.     tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
  239.  
  240.                     /* Right half expansion */
  241.     tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
  242.  
  243.                     /* Perform the salt permutation */
  244.                 /* al = (tr & sk[2]) | (tl & ~sk[2]); */
  245.                 /* ar = (tl & sk[2]) | (tr & ~sk[2]); */
  246.     al = sk[2] & (tl ^ tr);
  247.     ar = al ^ tr;
  248.     al ^= tl;
  249.  
  250.     al ^= sk[0];            /* XOR with the subkey */
  251.     ar ^= sk[1];
  252.  
  253.                     /* S-box lookup and permutation */
  254.     return (ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
  255.         | ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]);
  256. }
  257.  
  258.  
  259. /*
  260.  * Encrypt a block of 8 bytes of data with the given ICE key.
  261.  */
  262.  
  263. unsigned char *
  264. ice_key_encrypt (
  265.     const ICE_KEY        *ik,
  266.     const unsigned char    *ptext,
  267.     unsigned char        *ctext
  268. ) {
  269.     register int        i;
  270.     register unsigned long    l, r;
  271.  
  272.     l = (ptext[0] << 24) | (ptext[1] << 16) | (ptext[2] << 8) | ptext[3];
  273.     r = (ptext[4] << 24) | (ptext[5] << 16) | (ptext[6] << 8) | ptext[7];
  274.  
  275.     for (i = 0; i < ik->ik_rounds; i += 2) {
  276.         l ^= ice_f (r, ik->ik_keysched[i]);
  277.         r ^= ice_f (l, ik->ik_keysched[i + 1]);
  278.     }
  279.  
  280.     for (i = 0; i < 4; i++) {
  281.         ctext[3 - i] = r & 0xff;
  282.         ctext[7 - i] = l & 0xff;
  283.  
  284.         r >>= 8;
  285.         l >>= 8;
  286.     }
  287.  
  288.     return (ctext);
  289. }
  290.  
  291.  
  292. /*
  293.  * Decrypt a block of 8 bytes of data with the given ICE key.
  294.  */
  295.  
  296. unsigned char *
  297. ice_key_decrypt (
  298.     const ICE_KEY        *ik,
  299.     const unsigned char    *ctext,
  300.     unsigned char        *ptext
  301. ) {
  302.     register int        i;
  303.     register unsigned long    l, r;
  304.  
  305.     l = (ctext[0] << 24) | (ctext[1] << 16) | (ctext[2] << 8) | ctext[3];
  306.     r = (ctext[4] << 24) | (ctext[5] << 16) | (ctext[6] << 8) | ctext[7];
  307.  
  308.     for (i = ik->ik_rounds - 1; i > 0; i -= 2) {
  309.         l ^= ice_f (r, ik->ik_keysched[i]);
  310.         r ^= ice_f (l, ik->ik_keysched[i - 1]);
  311.     }
  312.  
  313.     for (i = 0; i < 4; i++) {
  314.         ptext[3 - i] = r & 0xff;
  315.         ptext[7 - i] = l & 0xff;
  316.  
  317.         r >>= 8;
  318.         l >>= 8;
  319.     }
  320.  
  321.     return (ptext);
  322. }
  323.  
  324.  
  325. /*
  326.  * Set 8 rounds [n, n+7] of the key schedule of an ICE key.
  327.  */
  328.  
  329. static void
  330. ice_key_sched_build (
  331.     ICE_KEY        *ik,
  332.     unsigned short    *kb,
  333.     int        n,
  334.     const int    *keyrot
  335. ) {
  336.     int        i;
  337.  
  338.     for (i=0; i<8; i++) {
  339.         register int    j;
  340.         register int    kr = keyrot[i];
  341.         ICE_SUBKEY        *isk = &ik->ik_keysched[n + i];
  342.  
  343.         for (j=0; j<3; j++)
  344.         (*isk)[j] = 0;
  345.  
  346.         for (j=0; j<15; j++) {
  347.         register int    k;
  348.         unsigned long    *curr_sk = &(*isk)[j % 3];
  349.  
  350.         for (k=0; k<4; k++) {
  351.             unsigned short    *curr_kb = &kb[(kr + k) & 3];
  352.             register int    bit = *curr_kb & 1;
  353.  
  354.             *curr_sk = (*curr_sk << 1) | bit;
  355.             *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15);
  356.         }
  357.         }
  358.     }
  359. }
  360.  
  361.  
  362. /*
  363.  * Set the key schedule of an ICE key.
  364.  */
  365.  
  366. void
  367. ice_key_set (
  368.     ICE_KEY            *ik,
  369.     const unsigned char    *key
  370. ) {
  371.     int        i;
  372.  
  373.     if (ik->ik_rounds == 8) {
  374.         unsigned short    kb[4];
  375.  
  376.         for (i=0; i<4; i++)
  377.         kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1];
  378.  
  379.         ice_key_sched_build (ik, kb, 0, ice_keyrot);
  380.         return;
  381.     }
  382.  
  383.     for (i = 0; i < ik->ik_size; i++) {
  384.         int            j;
  385.         unsigned short    kb[4];
  386.  
  387.         for (j=0; j<4; j++)
  388.         kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1];
  389.  
  390.         ice_key_sched_build (ik, kb, i*8, ice_keyrot);
  391.         ice_key_sched_build (ik, kb, ik->ik_rounds - 8 - i*8,
  392.                             &ice_keyrot[8]);
  393.     }
  394. }
  395.